package com.xd.core.bill.controller;

import com.xd.core.bill.service.IBQDemo;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class BlockQueueDome<T> implements IBQDemo<T> {
    private final List<T> queue;
    private final int size;
    private final ReentrantLock lock;
    private final Condition notFull;
    private final Condition notEmpty;

    public BlockQueueDome(int size) {
        this.queue = new ArrayList<>(size);
        this.size = size;
        this.lock = new ReentrantLock();
        this.notFull = lock.newCondition();
        this.notEmpty = lock.newCondition();
    }
    @Override
    public void put(T t) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() >= size){
                notFull.await();
            }
            queue.add(t);
            notEmpty.signal();
        }finally {
            lock.unlock();
        }

    }

    @Override
    public T take() throws InterruptedException {
        lock.lock();
        try {
            while (queue.isEmpty()){
                notEmpty.await();
            }
            T t = queue.remove(0);
            notFull.signal();
            return t;
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> taskQueue = new LinkedBlockingQueue<>(3
        );
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(1000);
                    String take = taskQueue.take();
                    System.out.println("消费"+take);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
        taskQueue.put("task1");      // 生产者添加任务
        System.out.println("放入"+"task1");
        taskQueue.put("task2");
        System.out.println("放入"+"task2");
        taskQueue.put("task3");
        System.out.println("放入"+"task3");
        System.out.println("执行完毕");

    }
}
